using System;
using System.Text;

namespace QUICRPC
{
    public class QuicProtocol
    {
        /// <summary>
        /// 定义协议消息类型的枚举，底层类型为 byte。
        /// </summary>
        public enum MessageType : byte {
            /// <summary>
            /// 客户端会话注册请求。
            /// </summary>
            SessionRegister,
            /// <summary>
            /// 客户端会话续期请求。
            /// </summary>
            SessionRenew,

            /// <summary>
            /// 服务器向客户端分派异步任务。
            /// </summary>
            AssignTask,
            /// <summary>
            /// 客户端向服务器返回任务执行结果。
            /// </summary>
            TaskResponse,
            /// <summary>
            /// 进行远程过程调用（RPC）请求。
            /// </summary>
            RpcCall,
            /// <summary>
            /// 发起文件传输请求。
            /// </summary>
            FileTransferRequest,
            /// <summary>
            /// 接受文件传输请求。
            /// </summary>
            FileTransferAccept,
            /// <summary>
            /// 拒绝文件传输请求。
            /// </summary>
            FileTransferReject,
            /// <summary>
            /// 传输文件数据块。
            /// </summary>
            FileTransferData,
            /// <summary>
            /// 客户端已收到任务。
            /// </summary>
            TaskReceived,
            /// <summary>
            /// 客户端任务正在执行中。
            /// </summary>
            TaskInProgress,
            /// <summary>
            /// 客户端任务已完成。
            /// </summary>
            TaskCompleted,
            /// <summary>
            /// 客户端任务执行失败。
            /// </summary>
            TaskFailed
        }

        public class Message
        {
            public MessageType Type { get; set; }
            public string Data { get; set; }

            public byte[] Serialize()
            {
                var dataBytes = Encoding.UTF8.GetBytes(Data);
                var typeByte = (byte)Type;
                var lengthBytes = BitConverter.GetBytes(dataBytes.Length);
                var result = new byte[1 + 4 + dataBytes.Length];
                result[0] = typeByte;
                Array.Copy(lengthBytes, 0, result, 1, 4);
                Array.Copy(dataBytes, 0, result, 5, dataBytes.Length);
                return result;
            }

            public static Message Deserialize(byte[] data)
            {
                if (data.Length < 5)
                {
                    return null;
                }
                var type = (MessageType)data[0];
                var length = BitConverter.ToInt32(data, 1);
                if (data.Length < 5 + length)
                {
                    return null;
                }
                var dataString = Encoding.UTF8.GetString(data, 5, length);
                return new Message { Type = type, Data = dataString };
            }
        }
    }
}